package com.tian.intercptor;

import com.tian.config.RedisCacheUtil;
import com.tian.dto.resp.UserInfoRespDto;
import com.tian.enums.ResultCode;
import com.tian.exception.BusinessException;
import com.tian.utils.UserCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2022年11月01日 17:24
 * <p>
 * 登陆校验
 */
@Aspect
@Component
@Slf4j
@Order(1)
public class LoginCheckAspect {
    @Resource
    private RedisCacheUtil redisCacheUtil;
    /**
     * 这里我们使用注解的形式
     * 当然，我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method
     * 切点表达式:   execution(...)
     * 接口请求参数、相应参数、耗时、路径等信息打印
     */
    @Around("@annotation(com.tian.annotation.LoginCheckAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();

        String authorization = request.getHeader("Authorization");
        if (!StringUtils.hasText(authorization)) {
            throw new BusinessException(ResultCode.UNAUTHORIZED);
        }
        log.info("token:{}", authorization);
        log.info("请求路径:{},请求方法:{},请求参数:{},请求头:{},请求IP:{}", request.getRequestURI(), request.getMethod(), request.getQueryString(), request.getHeader("User-Agent"), request.getRemoteAddr());
        UserInfoRespDto userInfoRespDto = redisCacheUtil.getCacheObject(authorization);
        if (userInfoRespDto == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED);
        }
        UserCacheUtil.setUser(userInfoRespDto);
        // 执行业务逻辑
        return joinPoint.proceed();

    }
}
